package com.liuqi.openai.model.embedding;

import com.liuqi.openai.data.embedding.Embedding;
import com.liuqi.openai.data.segment.TextSegment;
import com.liuqi.openai.model.OpenAiModelException;
import com.liuqi.openai.model.output.Response;
import java.util.List;

import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;

/**
 * Embedding模型，它可以将给定的文本转换成嵌入(文本的矢量表示)。
 *
 * @author liuqi
 * @date 2025/7/19
 * @see com.liuqi.openai.model.OpenAiEmbeddingModel
 **/
public interface EmbeddingModel {

    /**
     * Embedding
     *
     * @param text  需要Embedding的文本
     * @return
     * @throws OpenAiModelException
     */
    default Response<Embedding> embed(String text) throws OpenAiModelException {
        if (text == null || text.isEmpty()) {
            throw new OpenAiModelException("text cannot be null or empty");
        }

        Response<List<Embedding>> response = embed(singletonList(text));
        return Response.from(
                response.content().get(0),
                response.tokenUsage(),
                response.finishReason()
        );
    }

    /**
     * Embedding
     *
     * @param texts 需要Embedding的文本组
     * @return
     * @throws OpenAiModelException
     */
    Response<List<Embedding>> embed(List<String> texts) throws OpenAiModelException;

    default Response<Embedding> embedTextSegment(TextSegment textSegment) throws OpenAiModelException {
        if (textSegment == null) {
            throw new OpenAiModelException("textSegment cannot be null");
        }

        Response<List<Embedding>> response = embedTextSegment(singletonList(textSegment));
        return Response.from(
                response.content().get(0),
                response.tokenUsage(),
                response.finishReason()
        );
    }

    default Response<List<Embedding>> embedTextSegment(List<TextSegment> textSegments) throws OpenAiModelException {
        if (textSegments == null || textSegments.isEmpty()) {
            throw new OpenAiModelException("textSegments cannot be null or empty");
        }

        List<String> texts = textSegments.stream()
                .map(TextSegment::text)
                .collect(toList());
        return embed(texts);
    }

}
